package com.zyw.security.shiro.web.authc.tk.factory;

import com.zyw.security.shiro.LoginFrom;
import com.zyw.security.shiro.web.authc.tk.FormAuthcToken;
import com.zyw.security.shiro.web.authc.tk.SmsAuthcToken;
import com.zyw.security.shiro.web.authc.tk.WXMiniAppsAuthcToken;
import com.zyw.security.shiro.web.authc.tk.WeixinQYAuthcToken;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * shiro token factory
 *
 * @author zhangyw
 * @date 2018/2/26 10:03
 */
public class ShiroAuthcTokenFactory {

    /**
     * 登录 来源参数名, 参数值可以是 form, qywx, wx[微信], qq, sms[短信], wb[weibo]
     */
    protected static final String LOGIN_FROM_PARAMNAME = "lf";

    /**
     * 普通用户名密码登录
     */
    protected static final String DEFAULT_USERNAME_PARAM = "username";
    protected static final String DEFAULT_PASSWORD_PARAM = "password";
    protected static final String DEFAULT_REMEMBER_ME_PARAM = "rememberMe";

    /**
     * 手机短信验证码登录
     */
    protected static final String SMS_PHONE_PARAM = "phone";
    protected static final String SMS_CODE_PARAM = "sms_code";

    /**
     * 微信企业outh2认证，回传参数名
     */
    protected static final String WEIXIN_QY_CODE_PARAM = "code";
    protected static final String WEIXIN_QY_STATE_PARAM = "state";

    /**
     * 根据不同的 request 创建 AuthenticationToken，可创建token有
     * UsernamePasswordToken form 表单登录
     * WeixinQYAuthcToken 企业微信扫码登录
     *
     * @param request  req
     * @param response res
     * @return AuthenticationToken
     * @see org.apache.shiro.authc.UsernamePasswordToken
     * @see WeixinQYAuthcToken
     */
    public AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String host = getHost(request);

        String loginFrom = WebUtils.getCleanParam(request, LOGIN_FROM_PARAMNAME);

        // 默认form 表单登录
        loginFrom = loginFrom == null ? "form" : loginFrom;

        if (LoginFrom.form.name().equalsIgnoreCase(loginFrom)) { // 普通用户名密码登录

            String username = getRequestParam(request, DEFAULT_USERNAME_PARAM);
            String password = getRequestParam(request, DEFAULT_PASSWORD_PARAM);

            boolean rememberMe = isRememberMe(request);
            return new FormAuthcToken(username, password, rememberMe, host);
        }

        if (LoginFrom.sms.name().equalsIgnoreCase(loginFrom)) {// 短信登录
            String phone = getRequestParam(request, SMS_PHONE_PARAM);
            String smsCode = getRequestParam(request, SMS_CODE_PARAM);

            return new SmsAuthcToken(phone, smsCode, host);
        }

        if (LoginFrom.qywx.name().equalsIgnoreCase(loginFrom)) {// 企业微信登录

            String weixinAuthCode = getRequestParam(request, WEIXIN_QY_CODE_PARAM);
            String state = getRequestParam(request, WEIXIN_QY_STATE_PARAM);

            return new WeixinQYAuthcToken(weixinAuthCode, state, host);
        }

        if (LoginFrom.wxminiapp.name().equalsIgnoreCase(loginFrom)){
            String miniappAuthCode = getRequestParam(request, "wxminiapp_code");

            return new WXMiniAppsAuthcToken(miniappAuthCode);
        }

        return null;
    }

    private String getHost(ServletRequest request) {
        return request.getRemoteHost();
    }

    private boolean isRememberMe(ServletRequest request) {
        return WebUtils.isTrue(request, getRequestParam(request, DEFAULT_REMEMBER_ME_PARAM));
    }

    private String getRequestParam(ServletRequest request, String paramName) {
        return WebUtils.getCleanParam(request, paramName);
    }

}
